package aimozg.joglfw.bones;

import aimozg.joglfw.JoglApplication;
import aimozg.joglfw.Renderable;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class Bone {
	public double px = 0;
	public double py = 0;
	public double pz = 0;
	public double rotAngle = 0;
	public double rvx = 0;
	public double rvy = 0;
	public double rvz = 1;
	public double tx = 0;
	public double ty = 0;
	public double tz = 0;
	private Renderable renderable;
	private Bone parent = null;
	private LinkedList<Bone> children = new LinkedList<Bone>();
	private String name;


	@Override
	/**
	 * Клонирует численные параметры кости; parent -- null, child - пусты
	 */
	public Bone clone(){
		Bone b =  new Bone(name,null,renderable,px,py,pz,rotAngle,tx,ty,tz);
		b.rvx = rvx;
		b.rvy = rvy;
		b.rvz = rvz;
		return b;
	}

	public Bone(String name) {
		this.name = name;
	}
	public Bone(String name,Renderable renderable){
		this.name = name;
		this.renderable = renderable;
	}

	public void link(Bone child) {
		children.add(child);
	}

	public void unlink(Bone child) {
		children.remove(child);
	}

	public Bone(String name,Bone parent, Renderable renderable,double px, double py, double pz, double rotAngle, double tx, double ty, double tz) {
		this(name,parent, renderable,px, py, pz);
		this.rotAngle = rotAngle;
		this.tx = tx;
		this.ty = ty;
		this.tz = tz;
	}

	public Bone(String name,Bone parent, Renderable renderable,double px, double py, double pz) {
		this.parent = parent;
		this.name = name;
		if (parent!=null){
			parent.link(this);
		}
		this.renderable = renderable;
		this.px = px;
		this.py = py;
		this.pz = pz;
	}

	public void render(JoglApplication app) {
		app.pushMatrix();
		app.translate(px, py, pz);
		app.rotate(rotAngle, rvx, rvy, rvz);
		app.translate(tx, ty, tz);
		if (renderable!=null){
			renderable.render(app);
		}
		for (Bone child : children) {
			child.render(app);
		}
		app.popMatrix();
	}

	public List<Bone> children() {
		return Collections.unmodifiableList(children);
	}

	private BoneAnimation animation;
	public Bone animation(BoneAnimation animation){
		this.animation = animation;
		return this;
	}

	public void render(JoglApplication app, double progress) {
		if (animation != null){
			animation.apply(this,progress);
		}
		render(app);
	}

	public String name() {
		return name;
	}

	public void setRenderable(Renderable renderable) {
		this.renderable = renderable;
	}

	public Bone fullClone(Bone parent) {
		Bone b =  new Bone(name,parent,renderable,px,py,pz,rotAngle,tx,ty,tz);
		b.rvx = rvx;
		b.rvy = rvy;
		b.rvz = rvz;
		for (Bone child: children){
			child.fullClone(b);
		}
		return b;
	}
}
